/************************************************************
 * 文件名: choosefrienddialog.cpp
 * 功能描述: 实现选择好友对话框的具体逻辑，包括好友列表、已选好友管理等。
 * 作者: 李强
 * 创建日期: [请填写日期]
 * 修改历史: 
 ************************************************************/
#include "choosefrienddialog.h"

#include <QHBoxLayout>
#include <QScrollArea>
#include <QScrollBar>
#include <QPushButton>
#include <QPainter>

#include "debug.h"

///////////////////////////////
/// 选择好友窗口中的一个  元素/好友项
//////////////////////////////
ChooseFriendItem::ChooseFriendItem(ChooseFriendDialog *owner, const QString &userId, const QIcon &avatar, const QString &name, bool checked)
    : userId(userId)
{
    // 1.设置控件的基本属性
    this->setFixedHeight(50);
    this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    // 2.设置布局管理器
    QHBoxLayout *layout = new QHBoxLayout();
    layout->setSpacing(10);
    layout->setContentsMargins(20, 0, 20, 0);
    this->setLayout(layout);

    // 3,创建复选框
    checkBox = new QCheckBox();
    checkBox->setChecked(checked);
    checkBox->setFixedSize(25, 25);
    QString style = "QCheckedBox {background-color: transparent;} QCheckBox::indicator { width: 20px; height: 20px; image:url(:/recource/image/unchecked.png);}";
    style += "QCheckBox::indicator:checked { image:url(:/recource/image/checked.png);}";
    checkBox->setStyleSheet(style);

    // 4.创建头像
    avatarBtn = new QPushButton();
    avatarBtn->setFixedSize(40, 40);
    avatarBtn->setIconSize(QSize(40, 40));
    avatarBtn->setIcon(avatar);

    // 5.创建名字
    nameLabel = new QLabel();
    nameLabel->setText(name);
    nameLabel->setStyleSheet("QLabel { background-color: transparent;}");

    // 6.添加上述内容到布局管理器中
    layout->addWidget(checkBox);
    layout->addWidget(avatarBtn);
    layout->addWidget(nameLabel);

    // 7.连接信号槽
    connect(checkBox, &QPushButton::toggled, this, [=](bool checked)
            {
        if(checked){
            //勾选了复选框，把当前这个 Item 添加到右侧的已选择区域
            owner->addSelectedFriend(userId,avatar,name);
        }else{
            //取消勾选
            owner->deleteSelectedFriend(userId);
        } });
}

void ChooseFriendItem::paintEvent(QPaintEvent *event)
{
    (void)event;
    // 1.根据鼠标的进入状态，来来绘制不同颜色
    QPainter painter(this);
    if (isHover)
    {
        // 绘制成深色
        painter.fillRect(this->rect(), QColor(230, 230, 230));
    }
    else
    {
        // 绘制成浅色
        painter.fillRect(this->rect(), QColor(255, 255, 255));
    }
}

void ChooseFriendItem::enterEvent(QEnterEvent *event)
{
    (void)event;
    isHover = true;
    // update 相当于 " 更新界面 "
    this->update();
    // 或者
    // this->repaint();
}

void ChooseFriendItem::leaveEvent(QEvent *event)
{
    (void)event;
    isHover = false;
    this->update();
}

ChooseFriendDialog::ChooseFriendDialog(QWidget *parent) : QDialog(parent)
{
    // 1. 设置窗口的基本属性
    this->setWindowTitle("选择好友");
    this->setWindowIcon(QIcon(":/recource/image/weixin.jpg"));
    this->setFixedSize(750, 750);
    this->setStyleSheet("QDialog { background-color:rgb(255,255,255);}");
    this->setAttribute(Qt::WA_DeleteOnClose);

    // 2.创建水平布局管理器
    QHBoxLayout *layout = new QHBoxLayout();
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);
    this->setLayout(layout);

    // 3.针对左侧窗口进行初始化
    initLeft(layout);

    // 4. 针对右侧窗口进行初始化
    initRight(layout);
}

void ChooseFriendDialog::initLeft(QHBoxLayout *layout)
{
    // 1.创建滚动区域
    QScrollArea *scrollArea = new QScrollArea();
    scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    scrollArea->setWidgetResizable(true);
    scrollArea->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal { height: 0px;}");
    scrollArea->verticalScrollBar()->setStyleSheet("QScrollBar:vertical{ width: 2px; background-color:rgb(255,255,255);}");
    scrollArea->setStyleSheet("QScorllArea { border:none;}");
    layout->addWidget(scrollArea, 1);

    // 2.创建 QWidget 设置到滚动区域
    totalContainer = new QWidget();
    totalContainer->setStyleSheet("QWidget{ background-color: rgb(255,255,255);}");
    scrollArea->setWidget(totalContainer);

    // 3.创建左侧子窗口内部的  垂直布局管理器
    QVBoxLayout *vlayout = new QVBoxLayout();
    vlayout->setSpacing(0);
    vlayout->setContentsMargins(0, 0, 0, 0);
    vlayout->setAlignment(Qt::AlignTop);
    totalContainer->setLayout(vlayout);

    // 4.需要进一步添加 vlayout 内部的元素，才能看到效果
    // 先构造测试数据，后续连接服务器后，从服务器拿到真实的好友列表，在添加真实数据
    // #if TEST_UI
    //     QIcon yangAvatar(":/recource/image/yang.jpg");
    //     for (int i = 0; i < 30; i++)
    //     {
    //         this->addFriend(QString::number(1000 + i), yangAvatar, "张三" + QString::number(i), false);
    //     }
    // #endif
}

void ChooseFriendDialog::initRight(QHBoxLayout *layout)
{
    // 1. 创建右侧的布局管理器
    QGridLayout *gridLayout = new QGridLayout();
    gridLayout->setContentsMargins(20, 0, 20, 20);
    gridLayout->setSpacing(10);
    layout->addLayout(gridLayout, 1);

    // 2. 创建 "提示" label
    QLabel *tipLabel = new QLabel();
    tipLabel->setText("选择联系人");
    tipLabel->setFixedHeight(30);
    tipLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    tipLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    tipLabel->setStyleSheet("QLabel { font-size: 16px; font-weight:700;}");

    // 3. 创建 滚动区域
    QScrollArea *scrollArea = new QScrollArea();
    scrollArea->setWidgetResizable(true);
    scrollArea->verticalScrollBar()->setStyleSheet("QScrollBar:vertical { width: 2px; background-color: rgb(255,255,255);}");
    scrollArea->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal { height: 0px;}");
    scrollArea->setStyleSheet("QScrollArea{ border:none;}");
    scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    // 4. 创建滚动区域中的 QWidget
    selectedContainer = new QWidget();
    selectedContainer->setObjectName("selectedContainer");
    selectedContainer->setStyleSheet("#selectedContainer { background-color:rgb(255,255,255);}");
    scrollArea->setWidget(selectedContainer);

    // 5.创建 selecedContainer 中的垂直布局
    QVBoxLayout *vlayout = new QVBoxLayout();
    vlayout->setSpacing(0);
    vlayout->setContentsMargins(0, 0, 0, 0);
    vlayout->setAlignment(Qt::AlignTop);
    selectedContainer->setLayout(vlayout);

    // 6. 创建底部按钮
    QString style = "QPushButton { color:rgb(7,191,76); background-color:rgb(240,240,240); border:none;border-radius: 5px;}";
    style += "QPushButton:hovet{ background-color:rgb(220,220,220);} QPushButton:pressed{ background-color:rgb(200,200,200)};";

    QPushButton *okBtn = new QPushButton();
    okBtn->setFixedHeight(40);
    okBtn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    okBtn->setText("完成");
    okBtn->setStyleSheet(style);

    QPushButton *cancelBtn = new QPushButton();
    cancelBtn->setFixedHeight(40);
    cancelBtn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    cancelBtn->setText("完成");
    cancelBtn->setStyleSheet(style);

    // 7. 将上述控件添加到布局管理器中
    gridLayout->addWidget(tipLabel, 0, 0, 1, 9);
    gridLayout->addWidget(scrollArea, 1, 0, 1, 9);
    gridLayout->addWidget(okBtn, 2, 1, 1, 3);
    gridLayout->addWidget(cancelBtn, 2, 5, 1, 3);

    // 构造数据 测试界面
#if 0
    QIcon yangAvatar(":/recource/image/yang.jpg");
    for(int i =0;i<30;i++)
    {
        this->addSelectedFriend(yangAvatar,"张三"+ QString::number(i));
    }

#endif
}

void ChooseFriendDialog::addFriend(const QString &userId, const QIcon &avatar, const QString &name, bool checked)
{
    ChooseFriendItem *item = new ChooseFriendItem(this, userId, avatar, name, checked);
    totalContainer->layout()->addWidget(item);
}

void ChooseFriendDialog::addSelectedFriend(const QString &userId, const QIcon &avatar, const QString &name)
{
    ChooseFriendItem *item = new ChooseFriendItem(this, userId, avatar, name, true);
    selectedContainer->layout()->addWidget(item);
}

void ChooseFriendDialog::deleteSelectedFriend(const QString &userId)
{
    // 遍历 selectContainer 中的每一个 Item 对比每个 Item 中的userId ，是否是要删除的userId
    QVBoxLayout *vlayout = dynamic_cast<QVBoxLayout *>(selectedContainer->layout());

    // 由于是要 "遍历" + " 删除 " 需要从后往前进行
    for (int i = vlayout->count() - 1; i >= 0; --i)
    {
        auto *item = vlayout->itemAt(i);
        if (item == nullptr || item->widget() == nullptr)
        {
            continue;
        }
        ChooseFriendItem *chooseFriendItem = dynamic_cast<ChooseFriendItem *>(item->widget());
        // 判定当前的 Item 的 userId 是否需要删除
        if (chooseFriendItem->getUserId() != userId)
        {
            continue;
        }
        vlayout->removeWidget(chooseFriendItem);
        ///////////////////////////////////////
        /// 此处直接使用 delete 可能导致程序直接崩溃，因为 delete 该对象时，该对象内部的 QCheckBox 还在使用中（触发着信号槽）
        /// 改成 deleteLater，就相当于将 delete 操作委托给 Qt 自身来完成，告诉 Qt 框架，要删除的这个对象
        /// 至于啥时候删除  Qt 会确保在 Qt 自身用完了之后，去真正的删除
        // delete chooseFriendItem;
        chooseFriendItem->deleteLater();
    }

    // 再遍历一下左侧列表，把左侧列表中对应 item 的 checked 勾选状态取消
    QVBoxLayout *vlayoutLeft = dynamic_cast<QVBoxLayout *>(totalContainer->layout());
    for (int i = 0; i < vlayoutLeft->count(); ++i)
    {
        auto *item = vlayoutLeft->itemAt(i);
        if (item == nullptr || item->widget() == nullptr)
        {
            continue;
        }
        ChooseFriendItem *chooseFriendItem = dynamic_cast<ChooseFriendItem *>(item->widget());
        if (chooseFriendItem->getUserId() != userId)
        {
            continue;
        }
        // 取消 checked
        chooseFriendItem->getCheckBox()->setChecked(false);
    }
}
